package tt.dz.egobus.servicemanager.entities;

import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;
import org.hibernate.validator.constraints.NotBlank;
import tt.dz.egobus.base.entity.BaseEntity;
import tt.dz.egobus.bean.BusinessStatus;
import tt.dz.egobus.bean.CodeStatus;
import tt.dz.egobus.vo.KV;

import javax.persistence.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author Anson
 * @date 17-3-21
 * @name 司机绑定车的关系表
 * @since 1.0.2
 */
@Entity
@Table(name = "driver_register_bus_relative", schema = "servicemanager")
public class DriverRegisterBusRelative extends BaseEntity {


    private static final long serialVersionUID = -325300974521729386L;

    public static final KV<String, String> BUS_ALIAS = new KV<>("bus", "bus");

    static {
        List<KV<String, String>> aliaseList = new ArrayList<KV<String, String>>(1);
        aliaseList.add(BUS_ALIAS);
        Bus.ALIAS_LIST.put(DriverRegisterBusRelative.class, aliaseList);
    }

    /**
     * @author Anson
     * @date 17-3-27
     * @name 当前关系状态
     * 部分状态与{@link BusinessStatus}部分一致
     * @since 1.0.3
     */
    public static enum RelativeStatus implements CodeStatus {

        //0:未上线;10:已上线;15,抢单;20:开始;30:进行;40:完毕;50：取消行程;60,下线;-10:异常
        UN_ACTIVE(1, "未上线"), ACTIVE(10, "已上线"), GRAB_BUSINESS(15, "抢单"), BEGIN_BUSINESS(20, "开始"), BUSINESS(30, "进行"),
        FINISH(40, "完毕"), CANCEL(50, "取消行程"), DOWN(60, "下线"), EXCEPTION(-10, "异常");

        private int code;
        private String msg;

        RelativeStatus(int code, String msg) {
            this.code = code;
            this.msg = msg;
        }

        @Override
        public int getCode() {
            return code;
        }

        @Override
        public String getMsg() {
            return msg;
        }

        /**
         * @param code 状态码
         * @author Anson
         * @date 17-3-27
         * @name 根据状态码或去枚举
         * @since 1.0.2
         */
        public static final RelativeStatus getStatus(int code) {
            for (RelativeStatus status : RelativeStatus.values()) {
                if (status.getCode() == code) {
                    return status;
                }
            }
            return null;
        }

        /**
         * @param code   实际上的状态码
         * @param status 断言当前的状态
         * @author Anson
         * @date 17-3-27
         * @name
         * @since 1.0.3
         */
        public static final boolean isAssertCode(int code, RelativeStatus status) {
            return status == RelativeStatus.getStatus(code);
        }

        public static final boolean assertUnActive(int code) {
            return isAssertCode(code, UN_ACTIVE);
        }

        public static final boolean assertActive(int code) {
            return isAssertCode(code, ACTIVE);
        }

        public static final boolean assertGrabBusiness(int code) {
            return isAssertCode(code, GRAB_BUSINESS);
        }

        public static final boolean assertBeginBusiness(int code) {
            return isAssertCode(code, BEGIN_BUSINESS);
        }

        public static final boolean assertBusiness(int code) {
            return isAssertCode(code, BUSINESS);
        }

        public static final boolean assertFinish(int code) {
            return isAssertCode(code, FINISH);
        }

        public static final boolean assertCancel(int code) {
            return isAssertCode(code, CANCEL);
        }

        public static final boolean assertDown(int code) {
            return isAssertCode(code, DOWN);
        }

        public static final boolean assertException(int code) {
            return isAssertCode(code, EXCEPTION);
        }

        public static final boolean isAbleException(int code) {
            return !(assertBeginBusiness(code) || assertBusiness(code));
        }

        /**
         * @param code 当前状态码
         * @author Anson
         * @date 17-5-12
         * @name 判断当前是否存在车辆绑定服务
         * @since 1.0.4
         */
        public static final boolean isAliveBindBus(int code) {
            return isAssertCode(code, ACTIVE) || isAssertCode(code, BEGIN_BUSINESS) || isAssertCode(code, BUSINESS)
                    || isAssertCode(code, FINISH) || isAssertCode(code, CANCEL);
        }
    }

    /**
     * 确信当前处于激活状态
     *
     * @return
     */
    public boolean assertUnActive() {
        return RelativeStatus.assertUnActive(this.status);
    }

    /**
     * 确信当前处于激活状态
     *
     * @return
     */
    public boolean assertActive() {
        return RelativeStatus.assertActive(this.status);
    }

    /**
     * 确信当前处于抢单中状态
     *
     * @return
     */
    public boolean assertGrabBusiness() {
        return RelativeStatus.assertGrabBusiness(this.status);
    }

    /**
     * 确信当前处于开始状态
     *
     * @return
     */
    public boolean assertBeginBusiness() {
        return RelativeStatus.assertBeginBusiness(this.status);
    }

    /**
     * 确信当前处于进行状态
     *
     * @return boolean
     */
    public boolean assertBusiness() {
        return RelativeStatus.assertBusiness(this.status);
    }

    /**
     * 确信当前处于进行状态
     *
     * @return boolean
     */
    public boolean assertFinish() {
        return RelativeStatus.assertFinish(this.status);
    }

    /**
     * 确信当前处于取消状态
     *
     * @return boolean
     */
    public boolean assertCancal() {
        return RelativeStatus.assertCancel(this.status);
    }

    /**
     * 确信当前处于进行状态
     *
     * @return boolean
     */
    public boolean assertDown() {
        return RelativeStatus.assertDown(this.status);
    }

    /**
     * 确信当前处于异常状态
     *
     * @return boolean
     */
    public boolean assertException() {
        return RelativeStatus.assertException(this.status);
    }

    /**
     * 是否可以激活上线
     *
     * @return boolean
     */
    public boolean isAbleActive() {
        return this.assertUnActive();
    }


    /**
     * @author Anson
     * @date 17-3-30
     * @name 只要不处于抢单中, 业务中, 开始业务中状态都可以上报异常
     * @since 1.0.3
     */
    public boolean isAbleException() {
        return !(this.assertBusiness() || this.assertBeginBusiness() || this.assertGrabBusiness());
    }

    /**
     * @author Anson
     * @date 17-3-28
     * @name 确信当前是可以接单的状态 </br>常规模式下
     * @since 1.0.3
     */
    public boolean isAbleDoBeginBusiness() {
        return this.assertActive();
    }

    /**
     * @author Anson
     * @date 17-3-28
     * @name 确信当前是可以接单的状态 </br>抢单模式下
     * @since 1.0.3
     */
    public boolean isAbleDoBeginBusinessInGrab() {
        return this.assertGrabBusiness();
    }

    /**
     * 是否可以下线
     */
    public boolean isAbleDown() {
        return !(this.assertGrabBusiness() || assertBeginBusiness() || assertBusiness());
    }

    /**
     * 设置当前处于激活状态
     */
    public void setAbleUnActive() {
        this.status = RelativeStatus.UN_ACTIVE.getCode();
    }

    /**
     * 设置当前处于激活状态
     */
    public void setAbleActive() {
        this.status = RelativeStatus.ACTIVE.getCode();
    }

    /**
     * 设置当前处于开始状态
     */
    public void setAbleGrabBusiness() {
        this.status = RelativeStatus.GRAB_BUSINESS.getCode();
    }

    /**
     * 设置当前处于开始状态
     */
    public void setAbleBeginBusiness() {
        this.status = RelativeStatus.BEGIN_BUSINESS.getCode();
    }


    /**
     * 设置当前处于进行状态
     */
    public void setAbleBusiness() {
        this.status = RelativeStatus.BUSINESS.getCode();
    }

    /**
     * 设置当前处于进行状态
     */
    public void setAbleFinish() {
        this.status = RelativeStatus.FINISH.getCode();
    }

    /**
     * 设置当前处于取消状态
     */
    public void setAbleCancal() {
        this.status = RelativeStatus.CANCEL.getCode();
    }

    /**
     * 设置当前处于取消状态
     */
    public void setAbleDown() {
        this.status = RelativeStatus.DOWN.getCode();
    }

    /**
     * 设置当前处于异常状态
     */
    public void setAbleException() {
        this.status = RelativeStatus.EXCEPTION.getCode();
    }


    /**
     * busId
     */
    @Column(name = "bus_id")
    @NotBlank(message = "车的id不能为空")
    private String busId;

    /**
     * 车辆
     */
    @ManyToOne(targetEntity = Bus.class, fetch = FetchType.EAGER)
    @JoinColumn(name = "bus_id", insertable = false, updatable = false)
    @Fetch(FetchMode.JOIN)
    private Bus bus;
    /**
     * 司机id
     */
    @Column(name = "driver_id")
    @NotBlank(message = "司机id不能为空")
    private String driverId;

    /**
     * 司机真实姓名
     */
    @Column(name = "driver_name")
 /*   @NotBlank(message = "司机真实姓名不能为空")*/ private String driverName;


    /**
     * 司机手机号码
     **/
    @Column(name = "phone_number")
/*    @NotBlank(message = "司机手机号码不能为空")*/ private String phoneNumber;
    /**
     * 身份证号码
     **/
    @Column(name = "id_card")
  /*  @NotBlank(message = "司机身份证号码不能为空")*/ private String idCard;

    /**
     * 状态 0:未激活;10:激活;15,抢单;20:开始;30:进行;40:完毕;50：取消行程;60,下线;-10:异常
     */
    @Column(length = 10)
    private int status;

    /**
     * 是否失效
     */
    @Column(name = "is_validate")
    private boolean isValidate;


    /**
     * 创建时间
     */
    @Column(name = "create_time")
    private Date createTime;


    /**
     * 结束时间
     */
    @Column(name = "end_time")
    private Date endTime;


    public String getBusId() {
        return busId;
    }

    public void setBusId(String busId) {
        this.busId = busId;
    }

    public String getDriverId() {
        return driverId;
    }

    public void setDriverId(String driverId) {
        this.driverId = driverId;
    }

    public String getDriverName() {
        return driverName;
    }

    public void setDriverName(String driverName) {
        this.driverName = driverName;
    }

    public String getPhoneNumber() {
        return phoneNumber;
    }

    public void setPhoneNumber(String phoneNumber) {
        this.phoneNumber = phoneNumber;
    }

    public String getIdCard() {
        return idCard;
    }

    public void setIdCard(String idCard) {
        this.idCard = idCard;
    }

    public int getStatus() {
        return status;
    }

    public void setStatus(int status) {
        this.status = status;
    }

    public boolean isValidate() {
        return isValidate;
    }

    public void setValidate(boolean validate) {
        isValidate = validate;
    }

    public boolean getIsValidate() {
        return isValidate;
    }

    public void setIsValidate(boolean validate) {
        isValidate = validate;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    public Date getEndTime() {
        return endTime;
    }

    public void setEndTime(Date endTime) {
        this.endTime = endTime;
    }

    public Bus getBus() {
        return bus;
    }

    public void setBus(Bus bus) {
        this.bus = bus;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        DriverRegisterBusRelative that = (DriverRegisterBusRelative) o;

        if (status != that.status) return false;
        if (isValidate != that.isValidate) return false;
        if (busId != null ? !busId.equals(that.busId) : that.busId != null) return false;
        if (bus != null ? !bus.equals(that.bus) : that.bus != null) return false;
        if (driverId != null ? !driverId.equals(that.driverId) : that.driverId != null) return false;
        if (driverName != null ? !driverName.equals(that.driverName) : that.driverName != null) return false;
        if (phoneNumber != null ? !phoneNumber.equals(that.phoneNumber) : that.phoneNumber != null) return false;
        if (idCard != null ? !idCard.equals(that.idCard) : that.idCard != null) return false;
        if (createTime != null ? !createTime.equals(that.createTime) : that.createTime != null) return false;
        return endTime != null ? endTime.equals(that.endTime) : that.endTime == null;
    }

    @Override
    public int hashCode() {
        int result = busId != null ? busId.hashCode() : 0;
        result = 31 * result + (bus != null ? bus.hashCode() : 0);
        result = 31 * result + (driverId != null ? driverId.hashCode() : 0);
        result = 31 * result + (driverName != null ? driverName.hashCode() : 0);
        result = 31 * result + (phoneNumber != null ? phoneNumber.hashCode() : 0);
        result = 31 * result + (idCard != null ? idCard.hashCode() : 0);
        result = 31 * result + status;
        result = 31 * result + (isValidate ? 1 : 0);
        result = 31 * result + (createTime != null ? createTime.hashCode() : 0);
        result = 31 * result + (endTime != null ? endTime.hashCode() : 0);
        return result;
    }

    @Override
    public String toString() {
        return "DriverRegisterBusRelative{" + "busId='" + busId + '\'' + ", bus=" + bus + ", driverId='" + driverId +
                '\'' + ", driverName='" + driverName + '\'' + ", phoneNumber='" + phoneNumber + '\'' + ", idCard='" +
                idCard + '\'' + ", status=" + status + ", isValidate=" + isValidate + ", createTime=" + createTime +
                ", endTime=" + endTime + '}';
    }
}
